package com.shareware.common.utils

import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Intent
import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.view.View
import androidx.core.view.ViewCompat
import com.shareware.common.DEFAULT
import com.shareware.common.getContextGlobal
import java.text.DecimalFormat

/**
 * desc: 功能描述
 * email: mobiledeveloper@qq.com
 */

/**
 * 精确到指定位数
 */
fun Double.accuracyNum(bit: Int): String {
    if (bit == 0) {
        return this.toLong().toString()
    }
    val format = StringBuilder("#.0")
    for (num in 1 until bit) {
        format.append("0")
    }
    return DecimalFormat(format.toString()).format(this)
}

//inline fun <reified T> Gson.fromJson(json: String): T? = fromJson(json, T::class.java)

inline fun tryMethod(crossinline block: () -> Unit) {
    try {
        block()
    } catch (ex: Throwable) {
        logStackTrace(DEFAULT, ex)
    }
}

inline fun tryMethodErrorTrack(crossinline block: () -> Unit) {
    try {
        block()
    } catch (ex: Throwable) {
        logStackTrace(DEFAULT, ex)
        trackError(ex)
    }
}

inline fun tryMethodIgnore(crossinline block: () -> Unit) {
    try {
        block()
    } catch (ignore: Throwable) {
    }
}

inline fun View.layoutAvailable(crossinline block: () -> Unit) {
    if (ViewCompat.isLaidOut(this)) {
        block()
    } else {
        addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
            override fun onLayoutChange(
                v: View?, left: Int, top: Int, right: Int, bottom: Int,
                oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int,
            ) {
                removeOnLayoutChangeListener(this)
                block()
            }
        })
    }
}

fun Intent.createExplicitFromImplicitIntent(): Intent? {
    val resolveInfo = getContextGlobal().packageManager.resolveService(this, 0)
        ?: return null
    val packageName = resolveInfo.serviceInfo.packageName
    val className = resolveInfo.serviceInfo.name
    val explicitIntent = Intent(this)
    explicitIntent.component = ComponentName(packageName, className)
    return explicitIntent
}

private var iTrackDataAPI: Any? = null

@SuppressLint("PrivateApi")
fun trackError(error: String) {
//临时注掉，因自研埋点库下线
//    tryMethodIgnore {
//        if (iTrackDataAPI == null) {
//            val trackApiClass = Class.forName("com.android.track.sdk.TrackDataAPI")
//            iTrackDataAPI =
//                trackApiClass.cast(reflectPublicStaticMethod(trackApiClass, "instance") ?: return)
//        }
//        if (iTrackDataAPI == null) {
//            return
//        }
//        reflectPublicMethod(
//            iTrackDataAPI!!,
//            "track",
//            arrayOf(String::class.java, Map::class.java),
//            arrayOf("00", hashMapOf("error" to error))
//        )
//    }
}

@SuppressLint("PrivateApi")
fun trackError(ex: Throwable) {
    trackError(android.util.Log.getStackTraceString(ex))
}

private val handler by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
    Handler(Looper.getMainLooper())
}

private val handlerAsync by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
    val handlerThread = HandlerThread("common_thread")
    handlerThread.start()
    Handler(handlerThread.looper)
}

fun runInMainThread(runnable: Runnable) {
    if (Looper.getMainLooper().thread != Thread.currentThread()) {
        handler.post(runnable)
    } else {
        runnable.run()
    }
}

fun runInMainThreadDelay(runnable: Runnable, delayMillis: Long) {
    handler.postDelayed(runnable, delayMillis)
}

fun runInAsyncThread(runnable: Runnable) = handlerAsync.post(runnable)

fun runInAsyncThreadDelay(runnable: Runnable, delayMillis: Long) =
    handlerAsync.postDelayed(runnable, delayMillis)